package utils

import (
    "errors"
    "github.com/golang-jwt/jwt/v5"
    "golang.org/x/crypto/bcrypt"
    "time"
)

// HashPassword 用户密码加密
func HashPassword(password string) (string, error) {
    hash, err := bcrypt.GenerateFromPassword([]byte(password), 12)
    return string(hash), err
}

// GenerateJWT 生成JWT令牌
func GenerateJWT(username string) (string, error) {
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
        "username": username,
        "exp":      time.Now().Add(time.Hour * 72).Unix(),
    })
    tokenString, err := token.SignedString([]byte("secret"))
    return "Bearer " + tokenString, err
}

// CheckPassword 验证用户密码
func CheckPassword(password, hash string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
    return err == nil
}

// ParseJWT 验证JWT是否合规
func ParseJWT(tokenString string) (string, error) {
    // 去除Bearer
    if len(tokenString) > 7 && tokenString[:7] == "Bearer " {
        tokenString = tokenString[7:]
    }

    // 验证是否合规
    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        // 验证签名方法
        if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
            // 签名方法不正确
            return nil, errors.New("Unexpected signing method")
        }

        return []byte("secret"), nil
    })

    if err != nil {
        return "", err
    }

    // 验证用户名
    if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
        username, ok := claims["username"].(string)
        if !ok {
            return "", errors.New("Username claim is not string")
        }

        return username, nil
    }

    return "", err
}
